#include "tiny_cli.h"

static tiny_cli_table_t *tiny_cli_cmd_table = NULL; // 命令表指针

/**
 * @description: help
 * @param {int} argc
 * @param {char} *
 * @return {*}
 */
static void tiny_cli_help(int argc, char **argv)
{
    tiny_cli_table_t *p = tiny_cli_cmd_table;

    TINY_PRINTF("All commands:\n");
    while(p) 
    {
        TINY_PRINTF(" - %s\n", p->name); // 打印命令名称
        p = p->next; // 移动到下一个命令
    }
}

/**
 * @description: 初始化CLI模块
 * @return {*}
 */
int tiny_cli_init(void)
{
    tiny_cli_add_cmd("help", tiny_cli_help);
    return TINY_CLI_OK;
}

/**
 * @description: 添加命令
 * @param {char} *name
 * @param {int} argc
 * @param {char} *
 * @return {*}
 */
int tiny_cli_add_cmd(char *name, void (*func)(int argc, char **argv))
{
    tiny_cli_table_t *new_cmd = (tiny_cli_table_t *)TINY_MALLOC(sizeof(tiny_cli_table_t));
    if(new_cmd == NULL)
    {
        // 处理内存分配失败
        return TINY_CLI_ERR;
    }
    strncpy(new_cmd->name, name, sizeof(new_cmd->name) - 1);
    new_cmd->name[sizeof(new_cmd->name) - 1] = '\0'; // 确保字符串以'\0'结尾
    new_cmd->func = func;
    new_cmd->next = tiny_cli_cmd_table; // 将新命令添加到表头
    tiny_cli_cmd_table = new_cmd;
    return 0;
}

/**
 * @description: 处理字符串
 * @param {u16} lenth  需要处理的字符串长度
 * @param {u8} *str 字符串指针
 * @return {*}
 */
int tiny_cli_process_str(char *str)
{
    char *argv[TINY_CLI_MAX_ARGV] = {0};
    int argc = 0;
    tiny_cli_table_t *p = tiny_cli_cmd_table;

    if(str == NULL) 
    {
        return TINY_CLI_ERR; // 输入字符串为空
    }

    if(strlen(str) >= TINY_CLI_MAX_STR_LENGTH) 
    {
        TINY_PRINTF("Input command too long.\n");
        return TINY_CLI_ERR; // 输入字符串过长
    }

    // 分割命令和参数
    char buf[TINY_CLI_MAX_STR_LENGTH];
    strncpy(buf, str, sizeof(buf) - 1);
    buf[sizeof(buf) - 1] = '\0'; // 确保字符串以'\0'结尾
    char *token = strtok(buf, " ");
    while(token && argc < TINY_CLI_MAX_ARGV) 
    {
        argv[argc++] = token;
        token = strtok(NULL, " ");
    }

    if(argc == 0) 
    {
        TINY_PRINTF("No command entered.\n");
        return TINY_CLI_ERR; // 没有命令
    }

    // 查找命令
    while(p) 
    {
        if(strcmp(argv[0], p->name) == 0) 
        {
            p->func(argc, argv); // 调用对应命令函数
            return TINY_CLI_OK;
        }
        p = p->next;
    }

    // 未找到命令
    TINY_PRINTF("Command not found: %s\n", argv[0]);
    return TINY_CLI_ERR;
}
